package org.bookie.hibernate.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.bookie.hibernate.config.entries.ListenerElement;
import org.hibernate.cfg.AnnotationConfiguration;

/**
 * Global configuration object that will configure all aspects of contributed
 * configuration options
 * 
 * @author zubairov
 * 
 */
public class Configurator implements ApplicableElement {

	private Collection<ConfigElement> entries;

	/**
	 * Public constructor that accept a collection of contributions
	 * 
	 * @param contributions
	 */
	public Configurator(Collection<ConfigElement> contributions) {
		this.entries = contributions;
	}

	/**
	 * Apply configuration to the annotation configuration instance
	 * 
	 * @param configuration
	 */
	public void applyTo(AnnotationConfiguration configuration) {
		Map<String, Collection<String>> listeners = new HashMap<String, Collection<String>>();
		for (ConfigElement entry : entries) {
			if (entry instanceof ApplicableElement) {
				((ApplicableElement)entry).applyTo(configuration);
			}
			if (entry instanceof ListenerElement) {
				String type = ((ListenerElement)entry).getType();
				String instance = ((ListenerElement)entry).getClassName();
				Collection<String> registered = listeners.get(type);
				if (registered == null) {
					registered = new ArrayList<String>();
					listeners.put(type, registered);
				}
				registered.add(instance);
			}
		}
		Set<String> types = listeners.keySet();
		for (String type : types) {
			Collection<String> list = listeners.get(type);
			String[] objects = new String[list.size()];
			configuration.setListeners(type, list.toArray(objects));
		}
	}
}
